package top.mh.mybatis.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import top.mh.mybatis.pojo.Configuration;

import java.io.InputStream;
import java.util.List;
import java.util.Properties;

/**
 * @author mh
 * @version 1.0
 * @description xml全局配置文件解析类
 * @since 2024/2/2 15:37
 */
public class XMLConfigBuilder {

    private Configuration configuration;

    public XMLConfigBuilder() {
        configuration = new Configuration();
    }

    /**
     * 使用dom4j解析xml文件，封装configuration对象。
     * 解析xml全局配置文件：
     *  (1)解析数据源信息，并构建dataSource连接池对象。
     *  (2)解析全局配置文件引入的每个mapper.xml文件中的sql语句信息，并将sql信息存入到mapperStatement对象中。
     *
     * @param inputStream 全局配置文件输入流
     * @return configuration对象
     * @throws Exception
     */
    public Configuration parse(InputStream inputStream) throws Exception {
        // 1.使用dom4j解析全局配置xml文件
        // 将输入流加载成document对象
        Document document = new SAXReader().read(inputStream);
        // xml文件的根节点
        Element rootElement = document.getRootElement();

        // 获取xml配置文件中所有<property>标签
        List<Node> nodeList = rootElement.selectNodes("//property");
        Properties properties = new Properties();
        for (Node node : nodeList) {
            Element element = (Element) node;
            String name = element.attributeValue("name");
            String value = element.attributeValue("value");
            properties.setProperty(name, value);
        }

        // 根据xml配置文件读取到的信息,创建数据库连接池
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(properties.getProperty("driverClassName"));
        dataSource.setUrl(properties.getProperty("url"));
        dataSource.setUsername(properties.getProperty("username"));
        dataSource.setPassword(properties.getProperty("password"));

        // 将连接池封装到configuration对象中
        configuration.setDataSource(dataSource);

        // 2.解析mapper.xml文件信息
        List<Node> mapperList = rootElement.selectNodes("//mapper");
        for (Node node : mapperList) {
            Element element = (Element) node;
            // 获取到mapper.xml文件路径
            String path = element.attributeValue("resource");
            InputStream input = Resources.getResourceAsSteam(path);
            // 创建mapper xml文件解析器
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(configuration);
            xmlMapperBuilder.parse(input);
        }

        return configuration;
    }
}
